#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>

std::string FileName;
std::string TempFileName;
std::fstream PythonFileRead;
std::fstream PythonFileWrite;

int Begin(void);
std::string TempNameGen(void);
bool OpenFile(void);
void SubChar(const char *,const char *,std::string&);
void SubChar(std::string&);
void SubChar(const char *,std::string&);
bool ReadAndTranslateCode(void);

int main(void)
{
	std::string Order;
	TempNameGen();
	Order = std::string("py ") + TempFileName;
	while(1)
	{
		Begin();
		if(!OpenFile())
		{
			continue;
		}
		ReadAndTranslateCode();
		//模拟一下PythonIDLE运行的样子. 
		std::cout << "=============================== RESTART: " << FileName.c_str() << " ===============================" << std::endl;
		std::cout << std::endl; 
		system(Order.c_str());
		PythonFileWrite.clear();
		break;
	}
	//删除临时文件. 
	remove(TempFileName.c_str());
	PythonFileRead.close();
	PythonFileRead.clear();
	std::cout << std::endl;
	std::cout << ">>>运行结束,[Enter]退出程序." << std::endl;
	//防止程序一闪而过. 
	std::cin.get();
	
	return 0;
}

/**
*获取临时文件名.
*Return:None.
*/
std::string TempNameGen(void)
{
	TempFileName = tmpnam(NULL) + std::string(".py");
}

/**
*获取Python文件名.
*Return:None. 
*/
int Begin(void)
{
	std::cout << ">>>Please Enter the name of Python code file:" << std::endl << ">>>" << std::flush;
	std::getline(std::cin,FileName); 
	return 0;
}

/**
*打开中文Python代码文件.
*Return:1.打开成功返回true;2.打开失败返回false. 
*/
bool OpenFile(void)
{
	PythonFileRead.open(FileName.c_str(),std::ios::in);
	if(!PythonFileRead.is_open())
	{
		std::cerr << std::endl;
		std::cerr << "[Error]Error:Open File Fail!" << std::endl;
		std::cerr << "[Error]Please Enter the Right File Name!" << std::endl << std::endl;
		return false;
	}
	return true;
}

/**
*将中文Python代码转化为标准Python代码，储存在临时文件中.
*Return:true.
*/
bool ReadAndTranslateCode(void)
{
	std::string EachLineCode;
	PythonFileWrite.open(TempFileName.c_str(),std::ios::out | std::ios::trunc);
	
	//C++写入文件时，默认文件编码CP936(GBK),需要添加编码声明,否则无法使用中文变量标识符. 
	PythonFileWrite << "# -*- coding:gbk -*-" << std::endl;
	PythonFileWrite << "#!/usr/bin/python" << std::endl;
	while(!PythonFileRead.eof())
	{
		std::getline(PythonFileRead,EachLineCode);
		SubChar(EachLineCode);
		SubChar("eval",EachLineCode);
		SubChar(static_cast<const char*>("\t"),static_cast<const char*>("    "),EachLineCode);//抱歉我是空格党. 
		SubChar(static_cast<const char*>("（"),static_cast<const char*>("("),EachLineCode);
		SubChar(static_cast<const char*>("）"),static_cast<const char*>(")"),EachLineCode);
		SubChar(static_cast<const char*>("；"),static_cast<const char*>(";"),EachLineCode);
		SubChar(static_cast<const char*>("‘"),static_cast<const char*>("'"),EachLineCode);
		SubChar(static_cast<const char*>("’"),static_cast<const char*>("'"),EachLineCode);
		SubChar(static_cast<const char*>("："),static_cast<const char*>(":"),EachLineCode);
		SubChar(static_cast<const char*>("对于"),static_cast<const char*>("for"),EachLineCode);
		
		SubChar(static_cast<const char*>("是"),static_cast<const char*>("is"),EachLineCode);
		SubChar(static_cast<const char*>("在"),static_cast<const char*>("in"),EachLineCode);
		
		SubChar(static_cast<const char*>("导入"),static_cast<const char*>("import"),EachLineCode);
		SubChar(static_cast<const char*>("匿名函数"),static_cast<const char*>("lambda"),EachLineCode);
		/*因为接下来两个变量的字符串有相似性，字符串长度较大的在前，这是必要的*/
		SubChar(static_cast<const char*>("非局部变量"),static_cast<const char*>("nonlocal"),EachLineCode);
		SubChar(static_cast<const char*>("全局变量"),static_cast<const char*>("global"),EachLineCode);
		SubChar(static_cast<const char*>("删除"),static_cast<const char*>("del"),EachLineCode);
		SubChar(static_cast<const char*>("断言"),static_cast<const char*>("assert"),EachLineCode);
		SubChar(static_cast<const char*>("如果"),static_cast<const char*>("if"),EachLineCode);
		SubChar(static_cast<const char*>("或者为"),static_cast<const char*>("elif"),EachLineCode);
		SubChar(static_cast<const char*>("或者"),static_cast<const char*>("else"),EachLineCode);
		SubChar(static_cast<const char*>("循环"),static_cast<const char*>("while"),EachLineCode);
		SubChar(static_cast<const char*>("且"),static_cast<const char*>("and"),EachLineCode);
		SubChar(static_cast<const char*>("或"),static_cast<const char*>("or"),EachLineCode);
		SubChar(static_cast<const char*>("非"),static_cast<const char*>("not"),EachLineCode);
		SubChar(static_cast<const char*>("不等于"),static_cast<const char*>("!="),EachLineCode);
		SubChar(static_cast<const char*>("等于"),static_cast<const char*>("=="),EachLineCode);
		SubChar(static_cast<const char*>("<<赋值"),static_cast<const char*>("="),EachLineCode);
		SubChar(static_cast<const char*>("返回"),static_cast<const char*>("return"),EachLineCode);
		SubChar(static_cast<const char*>("类"),static_cast<const char*>("class"),EachLineCode);
		SubChar(static_cast<const char*>("跳出"),static_cast<const char*>("break"),EachLineCode);
		SubChar(static_cast<const char*>("继续"),static_cast<const char*>("continue"),EachLineCode);
		SubChar(static_cast<const char*>("字串"),static_cast<const char*>("str"),EachLineCode);
		SubChar(static_cast<const char*>("列表"),static_cast<const char*>("list"),EachLineCode);
		SubChar(static_cast<const char*>("字典"),static_cast<const char*>("dict"),EachLineCode);
		SubChar(static_cast<const char*>("元组"),static_cast<const char*>("tuple"),EachLineCode);
		SubChar(static_cast<const char*>("函数"),static_cast<const char*>("def"),EachLineCode);
		SubChar(static_cast<const char*>("从"),static_cast<const char*>("from"),EachLineCode);
		SubChar(static_cast<const char*>("作为"),static_cast<const char*>("as"),EachLineCode);
		SubChar(static_cast<const char*>("尝试"),static_cast<const char*>("try"),EachLineCode);
		SubChar(static_cast<const char*>("除开"),static_cast<const char*>("except"),EachLineCode);
		SubChar(static_cast<const char*>("最终"),static_cast<const char*>("finally"),EachLineCode);
		SubChar(static_cast<const char*>("抛出异常"),static_cast<const char*>("raise"),EachLineCode);
		SubChar(static_cast<const char*>("占位"),static_cast<const char*>("pass"),EachLineCode);
		SubChar(static_cast<const char*>("退让"),static_cast<const char*>("yield"),EachLineCode);
		
		SubChar(static_cast<const char*>("关于"),static_cast<const char*>("with"),EachLineCode);
		/*值*/
		SubChar(static_cast<const char*>("真"),static_cast<const char*>("True"),EachLineCode);
		SubChar(static_cast<const char*>("假"),static_cast<const char*>("False"),EachLineCode);
		SubChar(static_cast<const char*>("虚"),static_cast<const char*>("None"),EachLineCode);
		SubChar(static_cast<const char*>("自身"),static_cast<const char*>("self"),EachLineCode);
		/*内建函数*/
		SubChar(static_cast<const char*>("执行"),static_cast<const char*>("exec"),EachLineCode);
		SubChar(static_cast<const char*>("字串输入"),static_cast<const char*>("raw_input"),EachLineCode);
		SubChar(static_cast<const char*>("标准输入"),static_cast<const char*>("input"),EachLineCode);
		SubChar(static_cast<const char*>("标准输出"),static_cast<const char*>("print"),EachLineCode);
		SubChar(static_cast<const char*>("绝对值"),static_cast<const char*>("abs"),EachLineCode);
		SubChar(static_cast<const char*>("模商"),static_cast<const char*>("divmod"),EachLineCode);
		SubChar(static_cast<const char*>("打开"),static_cast<const char*>("open"),EachLineCode);
		SubChar(static_cast<const char*>("静态方法"),static_cast<const char*>("staticmethod"),EachLineCode);
		SubChar(static_cast<const char*>("所有"),static_cast<const char*>("all"),EachLineCode);
		SubChar(static_cast<const char*>("枚举容器"),static_cast<const char*>("enumerate"),EachLineCode);
		SubChar(static_cast<const char*>("取ASCII码"),static_cast<const char*>("ord"),EachLineCode);
		SubChar(static_cast<const char*>("任意"),static_cast<const char*>("any"),EachLineCode);
		SubChar(static_cast<const char*>("展开"),static_cast<const char*>("dir"),EachLineCode);
		SubChar(static_cast<const char*>("帮助"),static_cast<const char*>("help"),EachLineCode);
		SubChar(static_cast<const char*>("取长度"),static_cast<const char*>("len"),EachLineCode);
		SubChar(static_cast<const char*>("布尔型"),static_cast<const char*>("bool"),EachLineCode);
		SubChar(static_cast<const char*>("获取类型"),static_cast<const char*>("type"),EachLineCode);
		SubChar(static_cast<const char*>("比较类型"),static_cast<const char*>("isinstance"),EachLineCode);
		SubChar(static_cast<const char*>("次方运算"),static_cast<const char*>("pow"),EachLineCode);
		SubChar(static_cast<const char*>("求和运算"),static_cast<const char*>("sum"),EachLineCode);
		SubChar(static_cast<const char*>("超类字串"),static_cast<const char*>("basestring"),EachLineCode);
		SubChar(static_cast<const char*>("执行文件"),static_cast<const char*>("execfile"),EachLineCode);
		SubChar(static_cast<const char*>("鉴定类关系"),static_cast<const char*>("issubclass"),EachLineCode);
		SubChar(static_cast<const char*>("调用父类"),static_cast<const char*>("super"),EachLineCode);
		SubChar(static_cast<const char*>("转二进制"),static_cast<const char*>("bin"),EachLineCode);
		SubChar(static_cast<const char*>("文件打开"),static_cast<const char*>("file"),EachLineCode);
		SubChar(static_cast<const char*>("打开文件"),static_cast<const char*>("open"),EachLineCode);
		SubChar(static_cast<const char*>("迭代生成"),static_cast<const char*>("iter"),EachLineCode);
		SubChar(static_cast<const char*>("属性设置"),static_cast<const char*>("property"),EachLineCode);
		SubChar(static_cast<const char*>("序列过滤"),static_cast<const char*>("filter"),EachLineCode);
		SubChar(static_cast<const char*>("序列生成"),static_cast<const char*>("range"),EachLineCode);
		SubChar(static_cast<const char*>("属性设置"),static_cast<const char*>("property"),EachLineCode);
		SubChar(static_cast<const char*>("过滤序列"),static_cast<const char*>("filter"),EachLineCode);
		SubChar(static_cast<const char*>("列表创建"),static_cast<const char*>("range"),EachLineCode);
        SubChar(static_cast<const char*>("新字节数组"),static_cast<const char*>("bytearray"),EachLineCode);
        SubChar(static_cast<const char*>("浮点数"),static_cast<const char*>("float"),EachLineCode);
        SubChar(static_cast<const char*>("取Unicode码"),static_cast<const char*>("unichr"),EachLineCode);
        SubChar(static_cast<const char*>("格式化字串"),static_cast<const char*>("format"),EachLineCode);
		SubChar(static_cast<const char*>("对象调用检查"),static_cast<const char*>("callable"),EachLineCode);                
		if(EachLineCode == "\n")
		{
			continue;
		}
		PythonFileWrite << EachLineCode << std::endl;
	}
	PythonFileWrite.close();
	
	return true;
}

/**
*替换一行中所有存在的相关字符.
*Return:None. 
*/
void SubChar(const char * Origin,const char * Target,std::string& Code)
{
	int Pos;
	int IndexOrigin = 0;	//搜索起点 
	int TempIndexOrigin = 0;
	int LeftQuotationPos;
	int RightQuotationPos;
	LeftQuotationPos = Code.find("\"",IndexOrigin);
	if(LeftQuotationPos != std::string::npos)
	{
		RightQuotationPos = Code.find("\"",LeftQuotationPos + 1);
	}
	Pos = Code.find(Origin,IndexOrigin);
	while(std::string::npos != Pos)
	{
		if(IndexOrigin > Code.size())
		{
			break;
		}
		/*找到Pos在一对引号内，如果搜索完毕还没找到跳出*/
		while(!(Pos > LeftQuotationPos && Pos < RightQuotationPos && LeftQuotationPos != std::string::npos))
		{
			LeftQuotationPos = Code.find("\"",TempIndexOrigin);
			if(LeftQuotationPos != std::string::npos)
			{
				RightQuotationPos = Code.find("\"",LeftQuotationPos + 1);
			}
			/*找不到引号*/
			if(LeftQuotationPos == std::string::npos || RightQuotationPos == std::string::npos)
			{
				TempIndexOrigin = 0;
				break;
			}
			/*临时起点*/
			TempIndexOrigin = RightQuotationPos+1;
		}
		/*如果该字符串Pos位于双引号之内，则不改变它，增大搜索起点(IndexOrigin)*/
		while(Pos > LeftQuotationPos && Pos < RightQuotationPos && LeftQuotationPos != std::string::npos)
		{
			IndexOrigin = RightQuotationPos + 1;
			Pos = Code.find(Origin,IndexOrigin);
			LeftQuotationPos = Code.find("\"",IndexOrigin);
			if(LeftQuotationPos != std::string::npos)
			{
				RightQuotationPos = Code.find("\"",LeftQuotationPos + 1);
			}
		}
		/*搜索起点大于字符串长度，跳出.*/
		if(IndexOrigin > Code.size())
		{
			break;
		}
		/*Pos搜索无果，跳出*/
		if(Pos == std::string::npos)
		{
			break;
		}
		Code.replace(Pos,strlen(Origin),Target);
		Pos = Code.find(Origin,IndexOrigin);
		IndexOrigin = Pos+1;
	}
	return;
}

/**
*单独改变双引号.
*@param Code:string类字符串，文件的每一行代码.
*Retrun:None. 
*/
void SubChar(std::string& Code)
{
	int Pos;
	Pos = Code.find("“",0);
	while(std::string::npos != Pos)
	{
		Code.replace(Pos,strlen("“"),"\"");
		Pos = Code.find("“",0);
	}
	Pos = Code.find("”",0);
	while(std::string::npos != Pos)
	{
		Code.replace(Pos,strlen("”"),"\"");
		Pos = Code.find("”",0);
	}
	return;
}

/**
*eval函数略特殊，需要改动引号内的中文表达式.
*@param Target:目标:eval.
*@param Code:文件每一行的代码. 
*/
void SubChar(const char * Target,std::string& Code)
{
	int Pos;
	const char * Origin = "执行表达式";
	Pos = Code.find(Origin,0);
	while(std::string::npos != Pos)
	{
		Code.replace(Pos,strlen(Origin),Target);
		Pos = Code.find(Origin,0);
	}
	return;
}
